<template>
  <div class="header-container">
    <nav-bar
      :title="'生成订单'"
      :showLeftArrow="true"
      :leftText="'返回'"
      @click-left="back"
    >
    </nav-bar>
  </div>
  <div class="main-container">
    <div
      class="
        van-cell van-cell--center van-cell--clickable van-cell--borderless
        van-contact-card van-contact-card--edit
      "
    >
      <van-icon name="contact" size="1.5rem" />
      <div
        v-if="address != null"
        class="van-cell__value van-cell__value--alone van-contact-card__value"
      >
        <div>
          <span> 姓名： </span>
          <span>{{ address.receiverName }}</span>
        </div>
        <div>
          <span> 电话： </span>
          <span>{{ address.receiverPhone }}</span>
        </div>
        <div>
          <span> 地址： </span>
          <span>
            {{
              address.receiverProvince +
              " " +
              address.receiverCity +
              " " +
              address.receiverDistrict +
              " " +
              address.receiverAddress
            }}
          </span>
        </div>
      </div>
      <van-icon name="arrow" size="1.5rem" @click="selectAddress" />
    </div>
    <div></div>
    <template v-for="item of cartItems" :key="item.id">
      <van-card
        :num="item.quantity"
        :price="item.price"
        :title="item.productName"
        :thumb="item.productImgUrl"
        style="margin-top: 5px; margin-bottom: 5px"
      >
      </van-card>
    </template>
  </div>
  <div class="footer-container">
    <van-submit-bar
      :price="totalAmount"
      button-text="生成订单"
      @submit="createOrder"
    />
  </div>

  <van-popup
    closeable
    :close-on-click-overlay="false"
    v-model:show="paymentShown"
    position="bottom"
    :style="{ height: '30%' }"
    @close="closePay"
  >
    <div :style="{ width: '90%', margin: '0 auto', padding: '50px 0' }">
      <van-button
        :style="{ marginBottom: '10px' }"
        color="#1989fa"
        block
        @click="handlePayOrder(paymentType.ALI_PAY)"
      >
        支付宝支付
      </van-button>
      <van-button
        color="#4fc08d"
        block
        @click="handlePayOrder(paymentType.WECHAT)"
      >
        微信支付
      </van-button>
    </div>
  </van-popup>
</template>

<script lang="ts">
import NavBar from "@/components/NavBar.vue";
import OmsCartItem from "@/entity/OmsCartItem";
import OmsOrderCreationParam from "@/entity/OmsOrderCreationParam";
import OmsOrderUpdateParam from "@/entity/OmsOrderUpdateParam";
import OrderStatus from "@/entity/OmsOrderStatus";
import OrderType from "@/entity/OmsOrderType";
import PaymentType from "@/entity/OmsPaymentType";
import UmsAddress from "@/entity/UmsAddress";
import addressService from "@/services/address.service";
import cartItemService from "@/services/cart-item.service";
import orderService from "@/services/order.service";
import productService from "@/services/product.service";
import { AxiosError } from "axios";
import { Toast } from "vant";
import { defineComponent, onMounted, reactive, toRefs } from "vue";
import { useRoute, useRouter } from "vue-router";

type StateType = {
  id?: number | null;
  orderType: OrderType;
  cartItemIds: number[];
  cartItems: OmsCartItem[];
  addressId?: number | null;
  address?: UmsAddress | null;
  totalAmount: number;
  paymentShown: boolean;
};
export default defineComponent({
  components: {
    NavBar,
  },
  setup() {
    const paymentType = PaymentType;
    const route = useRoute();
    const router = useRouter();
    const state = reactive<StateType>({
      id: undefined,
      orderType: OrderType.FROM_CART,
      cartItemIds: [],
      cartItems: [],
      addressId: undefined,
      address: new UmsAddress(),
      totalAmount: 0,
      paymentShown: false,
    });

    onMounted(async () => {
      if (route.query.orderType != null) {
        state.orderType = route.query.orderType as OrderType;
      }
      if (state.orderType == OrderType.FROM_CART) {
        if (route.query.cartItemIds != null) {
          state.cartItemIds = Array.isArray(route.query.cartItemIds)
            ? route.query.cartItemIds.map((it) => Number(it))
            : [Number(route.query.cartItemIds)];
        }
      } else if (state.orderType == OrderType.DIRECTLY) {
        if (route.query.cartItems != null) {
          state.cartItems = JSON.parse(route.query.cartItems as string);
        }
      }
      if (route.query.addressId != null) {
        state.addressId = Number(route.query.addressId);
      }

      await load();
    });

    const load = async () => {
      try {
        if (state.addressId != null) {
          const address = await addressService.retrieve(state.addressId);
          state.address = address;
        } else {
          const address = await addressService.retrieveDefault();
          if (address == null) {
            selectAddress();
          }
          state.address = address;
        }

        if (state.orderType == OrderType.FROM_CART) {
          const cartItems = await cartItemService.query(state.cartItemIds);
          if (cartItems == null || cartItems.length <= 0) {
            router.push("/");
          }
          state.cartItems = [...cartItems];
        } else if (state.orderType == OrderType.DIRECTLY) {
        }

        let totalAmount = 0;
        state.cartItems.forEach((it) => {
          if (it == null || it.price == null || it.quantity == null) {
            return;
          }
          // 提交订单栏组件单位是 分
          totalAmount += it.price * it.quantity * 100;
        });
        state.totalAmount = totalAmount;
      } catch (e) {
        if (e instanceof AxiosError && e.response?.status == 401) {
          Toast.fail("请先登录");
          router.push("/login");
          return;
        }
        Toast.fail("加载失败");
        throw e;
      } finally {
      }
    };

    const back = () => {
      router.back();
    };

    const createOrder = async () => {
      try {
        const param: OmsOrderCreationParam = {
          orderType: state.orderType,
          addressId: state.address != null ? state.address.id : undefined,
          cartItems:
            state.orderType == OrderType.FROM_CART
              ? undefined
              : state.cartItems,
          cartItemIds:
            state.orderType == OrderType.FROM_CART
              ? state.cartItemIds
              : undefined,
        };
        const id = await orderService.create(param);
        state.id = id;
        state.paymentShown = true;
      } catch (e) {
        if (e instanceof AxiosError && e.response?.status == 401) {
          Toast.fail("请先登录");
          router.push("/login");
          return;
        }
        Toast.fail("加载失败");
        throw e;
      } finally {
      }
    };

    const handlePayOrder = async (paymentType: PaymentType) => {
      try {
        const param: OmsOrderUpdateParam = {
          id: state.id || -1,
          orderStatus: OrderStatus.UN_EXPRESSED,
        };
        const id = await orderService.update(param);
        Toast.success("支付成功");
        router.push("/order");
      } catch (e) {
        if (e instanceof AxiosError && e.response?.status == 401) {
          Toast.fail("请先登录");
          router.push("/login");
          return;
        }
        Toast.fail("加载失败");
        throw e;
      } finally {
      }
    };

    const closePay = () => {
      try {
        router.push("/order");
      } catch (e) {
        if (e instanceof AxiosError && e.response?.status == 401) {
          Toast.fail("请先登录");
          router.push("/login");
          return;
        }
        Toast.fail("加载失败");
        throw e;
      } finally {
      }
    };

    const selectAddress = () => {
      router.push({
        path: "/address",
        query: {
          ...route.query,
          from: "OrderPreview",
          addressId: state.address != null ? state.address.id : undefined,
        },
      });
    };

    return {
      ...toRefs(state),
      paymentType,
      back,
      createOrder,
      closePay,
      handlePayOrder,
      selectAddress,
    };
  },
});
</script>

<style scoped>
.van-card {
  background-color: #fff;
  margin-top: 0;
}
</style>